package com.tqyan.service.chat.impl.novel;

import com.tqyan.dal.mapper.NovelMapper;
import com.tqyan.dal.mapper.NovelSceneMapper;
import com.tqyan.model.controller.request.OpenAIChatMessageRequest;
import com.tqyan.model.controller.request.OpenAIChatRequest;
import com.tqyan.model.dto.*;
import com.tqyan.model.enums.ChatContentStatusEnum;
import com.tqyan.service.chat.AbstractChatPointService;
import com.tqyan.service.chat.ChatPointContent;
import com.tqyan.util.DateUtil;
import com.tqyan.util.SnowflakeUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * @description 小说类型
 * <p> <功能详细描述> </p>
 *
 * @author 陈晨
 * @date 2023/6/13 17:51
 */
@Service
@Slf4j
public class NovelNextSceneChatPointService extends AbstractChatPointService {

    @Autowired
    private NovelMapper novelMapper;
    @Autowired
    private NovelSceneMapper novelSceneMapper;
    @Autowired
    private NovelChatPointService novelChatPointService;
    @Autowired
    private NovelViewChatPointService novelViewChatPointService;
    @Autowired
    private NovelNextOptionChatPointService novelNextOptionChatPointService;

    @Override
    public String getPoint() {
        return ChatPointContent.NOVEL_NEXT_SCENE;
    }

    @Override
    public ChatContentDTO chatPoint(UserDTO user, UserSettingDTO userSetting, ChatDTO chat, String content) {
        // 1, 获取小说标题、下一幕
        // 2, 格式错误, 转默认对话
        content = content.replaceAll("：", ":");
        if (content.split(":").length < 2) {
            return null;
        }
        String title = content.split(":")[1].trim();
        if (title.split("_").length < 2) {
            return null;
        }
        String nextOption = title.split("_")[1].trim();
        title = title.split("_")[0].trim();

        // 3.1, 查询小说
        NovelDTO novel = novelMapper.queryByTitle(user.getId(), title);
        if (null == novel) {
            // 3.1, 小说不存在: 转查询
            String viewContent = ChatPointContent.NOVEL_VIEW + ":" + title;
            return novelViewChatPointService.chat(user, userSetting, chat, viewContent);
        }
        NovelSceneDTO novelSceneLast = novelSceneMapper.queryLastByNovel(user.getId(), novel.getId());

        // TODO 最后场景下一幕选项为空, 则直接入库对话，跳转下一幕

        // 4, 写场景
        // 记录对话
        ChatContentDTO question = super.createQuestion(user, userSetting, chat, content, null, null);
        ChatContentDTO answer = super.createAnswer(userSetting, question, null);
        // 请求问题, 答案流响应
        question.setContent(novelSceneLast.getContent()
                + "_" + novel.getTitle()
                + "_" + novel.getType()
                + "_" + nextOption);
        super.chatExecute(user, userSetting, chat, question, answer);
        return answer;
    }

    @Override
    protected boolean requestChatStop(UserDTO user, UserSettingDTO userSetting, ChatDTO chat
            , ChatContentDTO question, ChatContentDTO answer) {
        // 查询完成的答案
        ChatContentDTO completeAnswer = chatContentMapper.queryById(user.getId(), answer.getChatId(), answer.getId());

        // 添加小说场景
        String title = question.getContent().split("_")[1].trim();
        NovelDTO novel = novelMapper.queryByTitle(user.getId(), title);
        NovelSceneDTO novelSceneLast = novelSceneMapper.queryLastByNovel(user.getId(), novel.getId());
        NovelSceneDTO novelScene = new NovelSceneDTO();
        novelScene.setId(SnowflakeUtils.nextId());
        novelScene.setUserId(user.getId());
        novelScene.setNovelId(novel.getId());
        novelScene.setSeq(null == novelSceneLast ? 1 : novelSceneLast.getSeq() + 1);
        novelScene.setContent(completeAnswer.getContent());
        boolean result = novelSceneMapper.save(novelScene) > 0;
        log.info("[{}] userId={}, chatId={}, answerId={}, 添加小说场景: {}"
                , this.getPoint(), user.getId(), completeAnswer.getChatId(), completeAnswer.getId(), result);

        // 生成、上传文件
        novel.setFileName(novelChatPointService.uploadWord(novel));

        // 下一幕
        ChatContentDTO updateChatContent = new ChatContentDTO();
        updateChatContent.setId(completeAnswer.getId());
        updateChatContent.setChatId(completeAnswer.getChatId());
        updateChatContent.setStatus(ChatContentStatusEnum.COMPLETED.getValue());
        updateChatContent.setGptCompleteTime(DateUtil.now());
        updateChatContent.setOutputTokens(completeAnswer.getContent().length());
        updateChatContent.setContent(novelViewChatPointService.generateFileContent(
                novel, novelSceneMapper.queryLastByNovel(user.getId(), novel.getId())));
        result = chatContentMapper.update(updateChatContent) > 0;
        log.info("[{}] userId={}, chatId={}, answerId={}, novelScene={}, 更新回答内容: {}"
                , this.getPoint(), user.getId(), completeAnswer.getChatId(), completeAnswer.getId()
                , novelScene.getId(), result);
        return result;
    }

    @Override
    protected OpenAIChatRequest generateChatRequest(UserSettingDTO userSetting, ChatContentDTO question) {
        OpenAIChatRequest chatRequest = new OpenAIChatRequest();
        chatRequest.setModel(question.getGptModel());
        chatRequest.setTemperature(question.getTemperature() / 10D);
        OpenAIChatMessageRequest message = chatRequest.addMessage(question.getRole(), question.getContent());
        // 获取小说标题、类型
        String scene = question.getContent().split("_")[0].trim();
        String title = question.getContent().split("_")[1].trim();
        String type = question.getContent().split("_")[2].trim();
        String nextOption = question.getContent().split("_")[3].trim();
        // 设置对话内容
        String content = "“%s”\n\n"
                + "这是一部关于“%s”的“%s”小说，根据以上情节，继续写出下一个场景“%s”。"
                + "场景刻画要细腻，要有人物之间的交流，不要总结。";
        message.setContent(String.format(content, scene, title, type, nextOption));
        log.info("[{}] userId={}, chatId={}, chatRequest={}, 构建聊天请求"
                , this.getPoint(), question.getUserId(), question.getChatId(), chatRequest);
        return chatRequest;
    }

}


